#region

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Text.RegularExpressions;

#endregion

namespace Libraries
{
    public class EmailHelper
    {
        public static void SendMail(EmailDefinition emailDefinition, string smtpServer, int smtpPort, bool supportSSL,
                                    string userName, string password, List<object> listObject,
                                    string fileAttachment = null)
        {
            emailDefinition.EmailContent = ParseObjectToEmailTemplate(emailDefinition.EmailContent, listObject);
            emailDefinition.EmailTitle = ParseObjectToEmailTemplate(emailDefinition.EmailTitle, listObject);
            SendMail(emailDefinition, smtpServer, smtpPort, supportSSL, userName, password, fileAttachment);
        }

        public static string ParseObjectToEmailTemplate(string emailTemplate, List<Object> objectList)
        {
            var regex = new Regex("{(.*?)}");

            return regex.Replace(emailTemplate, m =>
            {
                var pName = m.Value.Substring(m.Value.LastIndexOf('.') + 1).TrimEnd('}');

                foreach(var value in from obj in objectList
                                     let pInfo = obj.GetType().GetProperty(pName)
                                     where pInfo != null
                                     select pInfo.GetValue(obj, null))
                {
                    return value == null ? string.Empty : value.ToString();
                }

                return string.Empty;
            });
        }

        public static void SendMail(EmailDefinition emailDefinition, string smtpServer, int smtpPort, bool supportSSL,
                                    string userName, string password, string fileAttachment = null)
        {
            var smtpClient = new SmtpClient();
            SetupSMTP(smtpServer, smtpPort, supportSSL, smtpClient, userName, password);
            var mailMessage = new MailMessage
            {
                From = new MailAddress(emailDefinition.EmailFrom)
            };
            if(!string.IsNullOrEmpty(fileAttachment))
            {
                mailMessage.Attachments.Add(new Attachment(fileAttachment));
            }
            if(!string.IsNullOrEmpty(emailDefinition.EmailTo))
            {
                foreach (var email in emailDefinition.EmailTo.Trim(' ', ';').Split(';'))
                {
                    mailMessage.To.Add(new MailAddress(email));
                }
            }
            SetupMailMessage(emailDefinition, mailMessage);
            smtpClient.Send(mailMessage);
        }

        private static void SetupMailMessage(EmailDefinition emailDefinition, MailMessage mailMessage)
        {
            if(!string.IsNullOrEmpty(emailDefinition.EmailCC))
            {
                foreach(var email in emailDefinition.EmailCC.Trim(' ',';').Split(';'))
                {
                    mailMessage.CC.Add(new MailAddress(email));
                }
            }
            if(!string.IsNullOrEmpty(emailDefinition.EmailBCC))
            {
                foreach (var email in emailDefinition.EmailBCC.Trim(' ', ';').Split(';'))
                {
                    mailMessage.Bcc.Add(new MailAddress(email));
                }
            }
            mailMessage.Subject = emailDefinition.EmailTitle;
            mailMessage.IsBodyHtml = emailDefinition.HtmlFormat;
            mailMessage.Body = emailDefinition.EmailContent;
        }

        private static void SetupSMTP(string smtpServer, int smtpPort, bool supportSSL, SmtpClient smtpClient,
                                      string userName, string password)
        {
            if(string.IsNullOrEmpty(smtpServer))
            {
                smtpClient.DeliveryMethod = SmtpDeliveryMethod.PickupDirectoryFromIis;
                smtpClient.Host = "127.0.0.1";
            }
            else
            {
                smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
                smtpClient.Host = smtpServer;
                smtpClient.EnableSsl = supportSSL;
                smtpClient.Port = smtpPort;
            }
            if(!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(password))
            {
                smtpClient.Credentials = new NetworkCredential(userName, password);
            }
        }
    }

    public class EmailDefinition
    {
        public string EmailFrom { get; set; }

        public string EmailTo { get; set; }

        public string EmailCC { get; set; }

        public string EmailBCC { get; set; }

        public string EmailTitle { get; set; }

        public string EmailContent { get; set; }

        public bool HtmlFormat { get; set; }
    }
}